
package com.mg.g2048.SD;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;

import android.content.ContextWrapper;
import android.graphics.Bitmap;
import android.util.Log;

import com.mg.g2048.Data.AppConfig;

public class SDHelper {
	
	/**
	 * 解压assets目录中GZIP文件
	 * 
	 * @param contextWrapper
	 *            上下文
	 * @param filePathInAssets
	 *            assets目录中文件路径
	 * @param outFilePath
	 *            输出文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean decompressGzipFileInAssetsDir(ContextWrapper contextWrapper,
			String filePathInAssets, String outFilePath, boolean overwrite) {
		if (contextWrapper == null || filePathInAssets == null || outFilePath == null)
			return false;
		
		InputStream inputStream = null;
		try {
			inputStream = contextWrapper.getAssets().open(filePathInAssets);
			if (inputStream == null)
				return false;
			
			return decompressByGzip(inputStream, outFilePath, overwrite);
		} catch (IOException e) {
			Log.i(AppConfig.Tag.FILE, "CAN NOT Find Asset file: " + filePathInAssets);
		} finally {
			if (inputStream == null)
				return false;

			try {
				inputStream.close();
			} catch (IOException e) {
				Log.i(AppConfig.Tag.FILE, "Error when closing!");
			}
		}
		
		return false;
	}

	/**
	 * 从assets目录中复制文件
	 * 
	 * @param contextWrapper
	 *            上下文
	 * @param filePathInAssets
	 *            assets目录中文件路径
	 * @param outFilePath
	 *            输出文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean copyFileFromAssetsDir(ContextWrapper contextWrapper,
			String filePathInAssets, String outFilePath, boolean overwrite) {
		if (contextWrapper == null || filePathInAssets == null || outFilePath == null)
			return false;
		
		InputStream inputStream = null;
		try {
			inputStream = contextWrapper.getAssets().open(filePathInAssets);
			if (inputStream == null)
				return false;
			
			return writeMediaData2File(inputStream, outFilePath, overwrite);
		} catch (IOException e) {
			Log.i(AppConfig.Tag.FILE, "CAN NOT Find Asset file: " + filePathInAssets);
		} finally {
			if (inputStream == null)
				return false;

			try {
				inputStream.close();
			} catch (IOException e) {
				Log.i(AppConfig.Tag.FILE, "Error when closing!");
			}
		}
		
		return false;
	}
	
	/**
	 * 将GZIP文件解压
	 * 
	 * @param inGzipFilePath
	 *            输入GZIP文件路径
	 * @param outFilePath
	 *            输出文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean decompressByGzip(String inGzipFilePath, String outFilePath, boolean overwrite) {
		if (inGzipFilePath == null || outFilePath == null)
			return false;

		// 文件已经存在
		if (exists(outFilePath)) {
			// 不覆盖
			if (!overwrite)
				return false;
		}
		
		File file = SDUtils.decompressByGzip(inGzipFilePath, outFilePath);
		if (file == null)
			return false;

		return true;
	}

	/**
	 * 将GZIP数据流解压到文件
	 * 
	 * @param inputStream
	 *            GZIP数据流
	 * @param outFilePath
	 *            输出文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean decompressByGzip(InputStream inputStream, String outFilePath, boolean overwrite) {
		if (inputStream == null || outFilePath == null)
			return false;

		// 文件已经存在
		if (exists(outFilePath)) {
			// 不覆盖
			if (!overwrite)
				return false;
		}
		
		File file = SDUtils.decompressByGzip(inputStream, outFilePath);
		if (file == null)
			return false;

		return true;
	}

	/**
	 * 将文件压缩为GZIP格式
	 * 
	 * @param inFilePath
	 *            输入文件路径
	 * @param outGzipFilePath
	 *            输出GZIP文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean compressByGzip(String inFilePath, String outGzipFilePath, boolean overwrite) {
		if (inFilePath == null || outGzipFilePath == null)
			return false;

		// 文件已经存在
		if (exists(outGzipFilePath)) {
			// 不覆盖
			if (!overwrite)
				return false;
		}
		
		File file = SDUtils.compressByGzip(inFilePath, outGzipFilePath);
		if (file == null)
			return false;

		return true;
	}

	/**
	 * 将输入数据流压缩为GZIP格式文件
	 * 
	 * @param inputStream
	 *            输入数据流
	 * @param outGzipFilePath
	 *            输出GZIP文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean compressByGzip(InputStream inputStream, String outGzipFilePath, boolean overwrite) {
		if (inputStream == null || outGzipFilePath == null)
			return false;

		// 文件已经存在
		if (exists(outGzipFilePath)) {
			// 不覆盖
			if (!overwrite)
				return false;
		}
		
		File file = SDUtils.compressByGzip(inputStream, outGzipFilePath);
		if (file == null)
			return false;

		return true;
	}

	/**
	 * 将 二维HashMap 的数据写入到文件中
	 * 
	 * @param hashMap2D
	 *            二维HashMap数据
	 * @param filePath
	 *            文件路径
	 * @param sortKey
	 *            是否对Key排序
	 * @param separator
	 *            分隔符
	 */
	public static void write2DHashMapToFile(HashMap<String, ArrayList<String>> hashMap2D, String filePath, boolean sortKey,
			String separator) {
		SDUtils.write2DHashMapToFile(hashMap2D, filePath, sortKey, separator, AppConfig.CHARACTER_SET);
	}

	/**
	 * 将 HashMap 的数据写入到文件中
	 * 
	 * @param hashMap
	 *            HashMap数据
	 * @param filePath
	 *            文件路径
	 * @param sortKey
	 *            是否对Key排序
	 * @param separator
	 *            分隔符
	 */
	public static void writeHashMap2File(HashMap<String, String> hashMap, String filePath, boolean sortKey, String separator) {
		SDUtils.writeHashMap2File(hashMap, filePath, sortKey, separator, AppConfig.CHARACTER_SET);
	}

	/**
	 * 将文件的数据读取到一个二维 HashMap 中
	 * 
	 * @param filePath
	 *            文件路径
	 * @param separator
	 *            数据之间的分割符
	 * @return 二维 HashMap
	 */
	public static HashMap<String, ArrayList<String>> read2DHashMapFromFile(String filePath, String separator) {
		return SDUtils.read2DHashMapFromFile(filePath, separator, AppConfig.CHARACTER_SET);
	}
	
	/**
	 * 将二维链表的数据写入到文件中
	 * 
	 * @param list2D
	 *            二维链表
	 * @param filePath
	 *            文件路径
	 * @param separator
	 *            分隔符
	 */
	public static void write2DListToFile(LinkedList<LinkedList<String>> list2D, String filePath, String separator) {
		SDUtils.write2DListToFile(list2D, filePath, separator, AppConfig.CHARACTER_SET);
	}

	/**
	 * 将链表的数据写入到文件中
	 * 
	 * @param list
	 *            链表
	 * @param filePath
	 *            文件路径
	 * @param separator
	 *            分隔符
	 */
	public static void writeListToFile(LinkedList<String> list, String filePath, String separator) {
		SDUtils.writeListToFile(list, filePath, separator, AppConfig.CHARACTER_SET);
	}
	
	/**
	 * 将文件的数据读取到一个二维链表中
	 * 
	 * @param filePath
	 *            文件路径
	 * @param separator
	 *            数据之间的分割符
	 * @return 二维链表
	 */
	public static LinkedList<LinkedList<String>> read2DListFromFile(String filePath, String separator) {
		return SDUtils.read2DListFromFile(filePath, separator, AppConfig.CHARACTER_SET);
	}

	/**
	 * 从文件获取图片的Bitmap数据
	 * 
	 * @param filePath
	 *            文件路径
	 * @return 图片的Bitmap数据。路径无效或解析文件出错，则返回null
	 */
	public static Bitmap getBitmapFromFile(String filePath) {
		return SDUtils.getBitmapFromFile(filePath);
	}

	/**
	 * 将图片的Bitmap数据写入文件中
	 * 
	 * @param bmp
	 *            图片的Bitmap数据
	 * @param filePath
	 *            文件路径
	 * @param quality
	 *            保存图片质量
	 */
	public static void writeBitmap2File(Bitmap bmp, String filePath, int quality) {
		SDUtils.writeBitmap2File(bmp, filePath, quality);
	}

	/**
	 * 将文本数据流写入文件
	 * 
	 * @param inputStream
	 *            多媒体数据流
	 * @param filePath
	 *            文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean writeTextData2File(InputStream inputStream, String filePath, boolean overwrite) {
		if (inputStream == null || filePath == null)
			return false;

		// 文件已经存在
		if (exists(filePath)) {
			// 不覆盖
			if (!overwrite)
				return false;
		}

		File file = SDUtils.writeTextData2File(inputStream, filePath);
		if (file == null)
			return false;

		return true;
	}

	/**
	 * 将多媒体数据流写入文件
	 * 
	 * @param inputStream
	 *            多媒体数据流
	 * @param filePath
	 *            文件路径
	 * @param overwrite
	 *            是否覆盖该路径上已有的文件
	 * @return 是否操作成功
	 */
	public static boolean writeMediaData2File(InputStream inputStream, String filePath, boolean overwrite) {
		if (inputStream == null || filePath == null)
			return false;

		// 文件已经存在
		if (exists(filePath)) {
			// 不覆盖
			if (!overwrite)
				return false;
		}

		File file = SDUtils.writeMediaData2File(inputStream, filePath);
		if (file == null)
			return false;

		return true;
	}

	/**
	 * 获取前段目录的全路径
	 */
	public static String getParentFullPath() {
		return getFullPath(AppConfig.Path.PARENT);
	}
	
	/**
	 * 获取程序设置文件的全路径
	 */
	public static String getSettingFileFullPath() {
		return getFullPath(AppConfig.Path.RECORD_DIR + "/" + AppConfig.Path.SETTING);
	}

	/**
	 * 获取SD卡上该路径的全路径
	 * 
	 * @param path
	 *            SD卡上的路径
	 * @return 含SD卡路径在内的全路径
	 */
	public static String getFullPath(String path) {
		return SDUtils.getFullPath(path);
	}

	/**
	 * 删除目录
	 * 
	 * @param dirPath
	 *            目录路径
	 */
	public static void deleteDir(String dirPath) {
		if (dirPath == null)
			return;

		File file = new File(dirPath);
		SDUtils.delete(file, true);
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath
	 *            文件路径
	 */
	public static void deleteFile(String filePath) {
		if (filePath == null)
			return;

		File file = new File(filePath);
		SDUtils.delete(file, false);
	}

	/**
	 * 新建目录
	 * 
	 * @param dirPath
	 *            目录路径
	 * @return 该目录的File，出错返回null
	 */
	public static File createDirs(String dirPath) {
		return SDUtils.createDirs(dirPath);
	}

	/**
	 * 新建文件
	 * 
	 * @param filePath
	 *            文件路径
	 * @return 该文件的File，出错返回null
	 */
	public static File createFile(String filePath) {
		return SDUtils.createFile(filePath);
	}

	/**
	 * 判断文件或目录的路径是否存在
	 * 
	 * @param path
	 *            文件或目录的路径
	 * @return 存在时返回true，不存在时返回false
	 */
	public static boolean exists(String path) {
		return SDUtils.exists(path);
	}

	/**
	 * 判断是否获取到了有效的SD卡路径
	 * 
	 * @return 有效时返回true，无效时返回false
	 */
	public static boolean gotValidSDPath() {
		return SDUtils.gotValidSDPath();
	}

	/**
	 * 获取SD卡的路径
	 * 
	 * @return SD卡的路径
	 */
	public static String getSDPath() {
		return SDUtils.getSDPath();
	}

	/**
	 * 初始化一些目录
	 */
	public static void initSomeDirs() {
		Log.i(AppConfig.Tag.FILE, "Initialize some directories...");

		// 没有正确初始化
		if (!gotValidSDPath())
			SDUtils.init();
		
		// 初始化新建一些必须的目录
		String[] initDirs = new String[] { AppConfig.Path.PARENT, AppConfig.Path.SRC_DATA_DIR, AppConfig.Path.RECORD_DIR };

		try {
			String fullDirPath = null;
			for (String initDir : initDirs) {
				fullDirPath = getFullPath(initDir);

				// 该目录不存在，则新建
				if (!exists(fullDirPath))
					SDUtils.createDirs(fullDirPath);
			}
		} catch (Exception e) {
			Log.i(AppConfig.Tag.FILE, "Failed to initialize some directories!");
			e.printStackTrace();
		}
	}

}
